package cn.elwy.rcp.ui.explorer.core.handler;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import org.tmatesoft.svn.core.SVNDepth;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.wc.SVNClientManager;
import org.tmatesoft.svn.core.wc.SVNRevision;

import cn.elwy.common.exception.RunException;
import cn.elwy.common.util.PathUtil;
import cn.elwy.rcp.core.model.ui.progress.ProgressMonitor;
import cn.elwy.rcp.ui.explorer.core.util.SVNClient;
import cn.elwy.rcp.ui.explorer.core.util.SvnUtil;
import cn.elwy.rcp.ui.explorer.core.vo.KeyValue;
import cn.elwy.rcp.ui.explorer.core.vo.ProjectConfig;

/**
 * SVN 更新代码
 * @author huangsq
 * @version 1.0, 2014-10-29
 * @since 1.0, 2014-10-29
 */
public class SvnUpdateHandler extends ProjectServiceHandler {

	private SVNClient svnClient;

	@Override
	public Object handler(ProjectConfig pc, ProgressMonitor monitor) {
		if (!pc.isAutoUpdate()) {
			return null;
		}
		List<KeyValue> kvList = getSvnKeyValues(pc);
		List<KeyValue> filterCheckOutPath = filterCheckOutPath(kvList);
		SVNRevision endVersion = SvnUtil.getSVNRevision(pc.getEndVersion());

		SVNClientManager clientManager = svnClient.getClientManager();
		try {
			// String destPath = PathUtil.getFilePath(pc.getOutputDir(), PathConst.OUTPUT_DOC_CHANGELOG_DIR);
			// int size = filterCheckOutPath.size();
			// int totalWork = size / 5;
			for (KeyValue keyValue : filterCheckOutPath) {
				File destFile = new File(keyValue.getValue().toString());
				if (SvnUtil.isWorkingCopy(destFile)) {
					// monitor.beginTask(name, totalWork);
					SvnUtil.cleanup(clientManager, destFile);
					SvnUtil.update(clientManager, destFile, endVersion, SVNDepth.INFINITY);
				} else {
					SvnUtil.checkout(clientManager, keyValue.getKey(), destFile, endVersion, SVNDepth.INFINITY);
				}
				// 输出变更记录
				//
			}
		} catch (SVNException e) {
			throw new RunException(e.getMessage(), e);
		}
		return true;
	}

	private List<KeyValue> getSvnKeyValues(ProjectConfig projectConfig) {
		List<KeyValue> kvList = new ArrayList<KeyValue>();

		String svnRoot = projectConfig.getScmUrl();
		String resourcePath = projectConfig.getResourcePath();

		String sourceDirectory = projectConfig.getSourceDirectory();
		String key = PathUtil.getFilePath(svnRoot, sourceDirectory);
		String value = PathUtil.getFilePath(resourcePath, sourceDirectory);
		KeyValue srcEntity = new KeyValue(key, value);
		kvList.add(srcEntity);

		key = PathUtil.getFilePath(svnRoot, projectConfig.getDocDirectory());
		value = PathUtil.getFilePath(resourcePath, projectConfig.getDocDirectory());
		KeyValue docEntity = new KeyValue(key, value);
		kvList.add(docEntity);

		key = PathUtil.getFilePath(svnRoot, projectConfig.getDemoDirectory());
		value = PathUtil.getFilePath(resourcePath, projectConfig.getDemoDirectory());
		KeyValue demoEntity = new KeyValue(key, value);
		kvList.add(demoEntity);

		key = PathUtil.getFilePath(svnRoot, projectConfig.getDbScriptDirectory());
		value = PathUtil.getFilePath(resourcePath, projectConfig.getDbScriptDirectory());
		KeyValue dbEntity = new KeyValue(key, value);
		kvList.add(dbEntity);

		key = PathUtil.getFilePath(svnRoot, projectConfig.getContainerDirectory());
		value = PathUtil.getFilePath(resourcePath, projectConfig.getContainerDirectory());
		KeyValue containerEntity = new KeyValue(key, value);
		kvList.add(containerEntity);

		key = PathUtil.getFilePath(svnRoot, projectConfig.getParentPom());
		value = PathUtil.getFilePath(resourcePath, projectConfig.getParentPom());
		KeyValue pomEntity = new KeyValue(key, value);
		kvList.add(pomEntity);

		return kvList;
	}

	/**
	 * 根据配置的SVN地址路径，获取需要检出的目录
	 * @param pathList svn相对地址
	 * @return 需要检查的地址
	 */
	private List<KeyValue> filterCheckOutPath(List<KeyValue> pathList) {
		List<KeyValue> resultList = new ArrayList<KeyValue>();
		for (KeyValue path : pathList) {
			boolean ignore = false;
			for (KeyValue result : resultList) {
				String key = path.getKey();
				String key2 = result.getKey();
				if (key.startsWith(key2)) {
					ignore = true;
					break;
				}
			}
			if (ignore) {
				continue;
			}
			for (KeyValue path2 : pathList) {
				String key = path.getKey();
				String key2 = path2.getKey();
				if (key.startsWith(key2)) {
					path = path2;
				}
			}
			resultList.add(path);
		}
		return resultList;
	}

	public SVNClient getSvnClient() {
		return svnClient;
	}

	public void setSvnClient(SVNClient svnClient) {
		this.svnClient = svnClient;
	}

}
